package org.smart4j.framework.common.helper;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.smart4j.framework.common.util.AnnotationUtil;
import org.smart4j.framework.common.util.ReflectionUtil;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

/**
 * IOC/DI助手类
 * 控制反转/依赖注入：开发者不通过new的方式来实例化类，而是交由框架自身来实例化类
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-01-30 18:18
 * tip Bean容器中的Bean对象都是单例的
 */
public class IOCHelper {
    static {
        //获取Bean容器
        final Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
        if (MapUtils.isNotEmpty(beanMap)) {
            //遍历容器
            for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
                //Bean类
                Class<?> beanClass = beanEntry.getKey();
                //Bean对象
                final Object beanInstance = beanEntry.getValue();
                //获取当前Bean类中的所有成员变量
                Field[] fields = beanClass.getFields();
                if (ArrayUtils.isNotEmpty(fields)) {
                    //遍历过滤被@Inject注解的成员变量
                    Arrays.stream(fields).filter(AnnotationUtil::isInjectAnnotated).forEach(beanField -> {
                        //获取Bean容器中当前Bean类对应的Bean对象
                        Class<?> beanFieldClass = beanField.getType();
                        Object beanFieldInstance = beanMap.get(beanFieldClass);
                        //通过反射对当前成员变量注入Bean对象
                        if (Objects.nonNull(beanFieldInstance)) {
                            ReflectionUtil.setFiled(beanInstance, beanField, beanFieldInstance);
                        }
                    });
                }
            }
        }
    }
}
